﻿using Common;
using Linguist.Acoustic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linguist.Flat
{
    /// <summary>
    /// Represents a unit in an SentenceHMMS
    /// </summary>
    public class UnitState:SentenceHMMState,IUnitSearchState
    {
        private IUnit unit;
        private HMMPosition position = HMMPosition.INTERNAL;


        /**
        /// Creates a UnitState. Gets the left and right contexts from the unit itself.
         *
        /// @param parent the parent state
        /// @param which  the index of the given state
        /// @param unit   the unit associated with this state
         */
        public UnitState(PronunciationState parent, int which, Unit unit) 
            :base("U", parent, which)
        {
            
            this.unit = unit;
            IUnit[] units = parent.getPronunciation().getUnits();
            int length = units.Length;

            // If the last phone is SIL, then we should be using
            // a word-ending phone for the last phone. Decrementing
            // length will make the phone before SIL the last phone.

            if (units[length - 1] == UnitManager.SILENCE && length > 1) {
                length--;
            }

            if (length == 1) {
                position = HMMPosition.SINGLE;
            } else if (which == 0) {
                position = HMMPosition.BEGIN;
            } else if (which == length - 1) {
                position = HMMPosition.END;
            }
        }


        /**
        /// Creates a UnitState with the given unit and HMM position.
         *
        /// @param unit     the unit associated with this state
        /// @param position the HMM position of this unit
         */
        public UnitState(IUnit unit, HMMPosition position) 
        {
            this.unit = unit;
            this.position = position;
        }


        /**
        /// Gets the unit associated with this state
         *
        /// @return the unit
         */
        public IUnit getUnit() 
        {
            return unit;
        }


        /**
        /// Returns true if this unit is the last unit of the pronunciation
         *
        /// @return <code>true</code> if the unit is the last unit
         */
        public Boolean isLast() 
        {
            return position == HMMPosition.SINGLE || position == HMMPosition.END;
        }


        /**
        /// Gets the name for this state
         *
        /// @return the name for this state
         */
        public String getName() 
        {
            return base.getName() + '<' + unit + '>';
        }


        /**
        /// Returns the value signature of this unit
         *
        /// @return the value signature
         */
        public String getValueSignature() {
            return unit.ToString();
        }


        /**
        /// Gets the pretty name for this unit sate
         *
        /// @return the pretty name
         */
        public String getPrettyName() {
            return unit.ToString();
        }


        /**
        /// Retrieves a short label describing the type of this state. Typically, subclasses of SentenceHMMState will
        /// implement this method and return a short (5 chars or less) label
         *
        /// @return the short label.
         */
        public String getTypeLabel() 
        {
            return "Unit";
        }


        /**
        /// Gets the position for this unit
         *
        /// @return the position for this unit
         */
        public HMMPosition getPosition() 
        {
            return position;
        }


        public Boolean isUnit() 
        {
            return true;
        }

        /// <summary>
        /// Returns the state order for this state type
        /// </summary>
        /// <returns></returns>
        override public int getOrder()
        {
            return 5;
        }

        IUnit IUnitSearchState.getUnit()
        {
            throw new NotImplementedException();
        }

        bool Common.ISearchState.isEmitting()
        {
            return base.isEmitting();
        }

        bool Common.ISearchState.isFinal()
        {
            return base.isFinal();
        }

        string Common.ISearchState.toPrettyString()
        {
            throw new NotImplementedException();
        }

        string Common.ISearchState.getSignature()
        {
            throw new NotImplementedException();
        }

        Common.IWordSequence Common.ISearchState.getWordHistory()
        {
            throw new NotImplementedException();
        }

        object Common.ISearchState.getLexState()
        {
            throw new NotImplementedException();
        }

        int Common.ISearchState.getOrder()
        {
            throw new NotImplementedException();
        }
    }
}
